package edu.mtu.citizenscience.streamapplication.activity.main;

import edu.mtu.citizenscience.streamapplication.activity.DBHelper;
import edu.mtu.citizenscience.streamapplication.activity.HTMLView;
import edu.mtu.citizenscience.streamapplication.activity.R;
import edu.mtu.citizenscience.streamapplication.activity.R.layout;
import edu.mtu.citizenscience.streamapplication.activity.R.menu;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.support.v4.app.NavUtils;
import android.annotation.TargetApi;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Build;

/**
 * @author Bryan Becker <bcbecker@mtu.edu>
 * @copyright (c) 2013 MichiganTech <http://www.mtu.edu>
 * 
 * Location Activity that provides data input fields for users
 * to input primary/introductory information about their report
 * that will be stored in the Location table in the database.
 * 
 * **NOTE** Still need to work on a latitude and longitude
 * fields and also auto generating GPS coordinates.
 */
public class SCLocationActivity extends Activity {

    // reference var for passing the row id between activities
	public static final String ROW_ID = "ROW_ID";
    // reference var for retrieving the boolean first time from previous activities
	public static final String FIRST_TIME = "FIRST_TIME";
	
	//our row id for the Location table
	private Long rowID;
	//boolean that tells us if this is the first time Location Activity has been created for a report
	private boolean firstTime;
	
	//database helper
	private DBHelper myDbHelper;
	
	// Elements of the ui to get data from
    private EditText streamText;
    private EditText countyText;
    private EditText roadText;
    private EditText crossingText;
    private EditText townshipText;
    private EditText crossingOther;
    private EditText adjacentOther;
    private TextView header;  
    private Spinner crossingType;    
    private CheckBox USA;
    private CheckBox state;
    private CheckBox local;
    private CheckBox est;
    private CheckBox otherCheck;
    
    //cursor for our reports
    private Cursor report;
    
	/**
	 * Report Guide Activity creation handler
	 * 
	 * @param   savedInstanceState - Bundle - Bundle with launch info
	 * @return	void
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// set up the content view and the custom header bar
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.activity_sclocation);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title);
		
		//open the database
		myDbHelper = new DBHelper(this);
		myDbHelper.open();
		
		//set the custom header title to "Location Data"
		header = (TextView) findViewById(R.id.header_text);
		header.setText("Location Data");
		
		//initialize our ui elements 
		streamText = (EditText) findViewById(R.id.stream);
		countyText = (EditText) findViewById(R.id.county);
		roadText = (EditText) findViewById(R.id.road);
		crossingText = (EditText) findViewById(R.id.crossing);
		townshipText = (EditText) findViewById(R.id.township);
		crossingOther = (EditText) findViewById(R.id.crossingOther);
		adjacentOther = (EditText) findViewById(R.id.adjacentOther);
		crossingType = (Spinner) findViewById(R.id.crossingType);
		
		// set up adapter for spinner so we can set it later
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this, R.array.crossing_type, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        crossingType.setAdapter(adapter);
		
        //initialize our check box elements
		USA = (CheckBox) findViewById(R.id.USA);
		state = (CheckBox) findViewById(R.id.state);
		local = (CheckBox) findViewById(R.id.local);
		est = (CheckBox) findViewById(R.id.privateEst);
		otherCheck = (CheckBox) findViewById(R.id.otherCheck);
		
		// listen to other check box
		CheckOnItemSelectedListener checkListener = new CheckOnItemSelectedListener();
		checkListener.loadView(adjacentOther);
		otherCheck.setOnCheckedChangeListener(checkListener);
		
		//set the other check box to disabled
		crossingOther.setEnabled(false);
		adjacentOther.setEnabled(false);
		
		//get the row id from the previous activity (default to -1 otherwise)
		rowID = this.getIntent().getLongExtra(this.ROW_ID, -1);
		//get the first time boolean from the previous activity (default to false otherwise)
		firstTime = this.getIntent().getBooleanExtra(this.FIRST_TIME, false);
		
		//populate our fields for existing data
		populateFields();

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.sclocation, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			// This ID represents the Home or Up button. In the case of this
			// activity, the Up button is shown. Use NavUtils to allow users
			// to navigate up one level in the application structure. For
			// more details, see the Navigation pattern on Android Design:
			//
			// http://developer.android.com/design/patterns/navigation.html#up-vs-back
			//
			NavUtils.navigateUpFromSameTask(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	/**
	 * Populate the fields in our layout with our existing data from the database.
	 * 
	 * @param   void
	 * @return	void
	 */
    private void populateFields() {
    	//fetch the row given the row id from the database and get the cursor
    	report = myDbHelper.fetchReport(rowID, "Location");
    	
    	//if there exists a result in the cursor (there is data)
        if (report.getCount() == 1) {
        	//set up the ui elements to display the data from the database
            streamText.setText(report.getString(report.getColumnIndexOrThrow("stream_name")));
            countyText.setText(report.getString(report.getColumnIndexOrThrow("county")));
            roadText.setText(report.getString(report.getColumnIndexOrThrow("road_name")));
            crossingText.setText(report.getString(report.getColumnIndexOrThrow("crossing_name")));
            townshipText.setText(report.getString(report.getColumnIndexOrThrow("township")));
            
            //If else statements for case that spinner is on other and the other text box is required
            if(getSpinnerIndex(crossingType,report.getString(report.getColumnIndexOrThrow("type_of_crossing"))) == -1){
            	crossingOther.setEnabled(true);
            	crossingType.setSelection(getSpinnerIndex(crossingType, "Other"));
            	crossingOther.setText(report.getString(report.getColumnIndexOrThrow("type_of_crossing")));
            }
            else{
            	crossingType.setSelection(getSpinnerIndex(crossingType, report.getString(report.getColumnIndexOrThrow("type_of_crossing"))));
            }
            
            //cases for check boxes 
            //stored as flags in the database and also the potential 'other' field
            String boxes = report.getString(report.getColumnIndexOrThrow("adj_landowners"));
            if(boxes.charAt(0) == '1'){
            	USA.setChecked(true);
            }
            else{
            	USA.setChecked(false);
            }
            if(boxes.charAt(1) == '1'){
            	state.setChecked(true);
            }
            else{
            	state.setChecked(false);
            }
            if(boxes.charAt(2) == '1'){
            	local.setChecked(true);
            }
            else{
            	local.setChecked(false);
            }
            if(boxes.charAt(3) == '1'){
            	est.setChecked(true);
            }
            else{
            	est.setChecked(false);
            }
            if(boxes.charAt(4) == '1'){
        		adjacentOther.setEnabled(true);
            	otherCheck.setChecked(true);
            	adjacentOther.setText(boxes.subSequence(5, boxes.length()));
            }
            else{
            	otherCheck.setChecked(false);
            }      
        }
    }
    
	/**
	 * Save the data entered into our activity and store it in the Location table.
	 * 
	 * @param   void
	 * @return	long - the row id of the row we stored data in 
	 */
    private long saveLocation(){
    	String spinnerOther;
    	
    	// check the spinner other and save its data
    	if(crossingType.getSelectedItem().toString().equals("Other")){
    		spinnerOther = crossingOther.getText().toString();
    	}
    	else{
    		spinnerOther = crossingType.getSelectedItem().toString();
    	}
    	
    	//retrieve data from the check boxes and store it in the boxes string
    	String boxes = "";
    	if(USA.isChecked()){
    		boxes = boxes.concat("1");
    	}
    	else{
    		boxes = boxes.concat("0");
    	}
    	if(state.isChecked()){
    		boxes = boxes.concat("1");
    	}
    	else{
    		boxes = boxes.concat("0");
    	}
    	if(local.isChecked()){
    		boxes = boxes.concat("1");
    	}
    	else{
    		boxes = boxes.concat("0");
    	}
    	if(est.isChecked()){
    		boxes = boxes.concat("1");
    	}
    	else{
    		boxes = boxes.concat("0");
    	}
    	if(otherCheck.isChecked()){
    		boxes = boxes.concat("1");
    		boxes = boxes.concat(adjacentOther.getText().toString());
    	}
    	else{
    		boxes = boxes.concat("0");
    	}
    	
    	//if we are not editing an existing report
		if(report.getCount() == 0){
			//store the data in the Location table by creating a new row
			return myDbHelper.createLocation(streamText.getText().toString(),
					countyText.getText().toString(),
					roadText.getText().toString(),
					crossingText.getText().toString(),
					townshipText.getText().toString(),
					spinnerOther,
					boxes,
					(float)0.0,
					(float)0.0);
		}
		//if we are editing an existing row in the Location table
		else{
			//update our row in the Location table with our new data
			myDbHelper.updateLocation(rowID,
					streamText.getText().toString(),
					countyText.getText().toString(),
					roadText.getText().toString(),
					crossingText.getText().toString(),
					townshipText.getText().toString(),
					spinnerOther,
					boxes, 
					(float)0.0,
					(float)0.0);
			
			//return our row id
			return rowID;
		}
    }
    
	/**
	 * onClick activity for the Save button.
	 * 
	 * @param view - View - responsible for drawing UI components and event handling
	 * @return	void
	 */
	public void cont(View view) {
		//save the location of our data and get the row id of our row
		rowID = saveLocation();
		//close the database
		myDbHelper.close();
		
		//if this is the first time we have created a Location Activity for our report
		if(firstTime){
			//create a new Report Guide Activity giving our row id
			Intent intent = new Intent(this, ReportGuide.class);
			intent.putExtra(ROW_ID, rowID);
		    startActivity(intent);
		}
	    
		//end this activity
		this.finish();
	}
	
	/**
	 * onClick activity for the Cancel button.
	 * 
	 * @param view - View - responsible for drawing UI components and event handling
	 * @return	void
	 */
	public void cancel(View view){
		//end this activity without saving any information
		this.finish();
	}
	
	/**
	 * Helper method for finding out where a specific element is located in a spinner
	 * 
	 * @param spin - Spinner - android spinner
	 * @param str - String - element we are looking for in the spinner
	 * @return	void
	 */
	private int getSpinnerIndex(Spinner spin, String str)
    {
    	Adapter adapter = spin.getAdapter();
    	for(int i=0; i < adapter.getCount(); i++)
    	{
    		if(adapter.getItem(i).toString().equals(str))			
    			return i;
    	}
    	return -1;
    }
	
	/**
	 * Override the back button for this activity which should
	 * close our database and finish the activity. Similar to cancel.
	 * 
	 * @param void
	 * @return	void
	 */
	@Override
    public void onBackPressed() {
        super.onBackPressed();   
        myDbHelper.close();
        this.finish();
    }
	
	/**
	 * onClick activity for the Tutorial button.
	 * 
	 * @param view - View - responsible for drawing UI components and event handling
	 * @return	void
	 */
	public void tutorial(View view){
		//create a new HTML View Activity giving it the file path for the HTML we want to display
		Intent intent = new Intent(this, HTMLView.class);
		intent.putExtra(HTMLView.PATH, "file:///android_asset/location.html");
		this.startActivity(intent);
	}
}
